/**
 * 
 */
package com.server;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.util.Objects;

import com.tool.Log;
import com.tool.Parameter;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.io.watch.SimpleWatcher;
import cn.hutool.core.io.watch.WatchMonitor;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * @author w.weizhen
 *
 */
public class StartServer 
{
    //启动服务
    public static void run()
    {
        //扫描文件,生成索引
        scan();
        
        //监听文件变化
        monitor();
        
        //创建服务
        createServer();
    }
    
    //创建服务
    private static void createServer()
    {
        HttpUtil.createServer(Parameter.port)
        .setRoot(Parameter.tmp_path)
        .start();
    }
    
    private static void monitor()
    {
        Log.log("创建文件监听");
        WatchMonitor.createAll(FileUtil.file(Parameter.local_file), new SimpleWatcher(){
            @Override
            public void onCreate(WatchEvent<?> event, Path currentPath) {
                Log.log("文件被创建: " + event.context());
                scan();
            }
            @Override
            public void onModify(WatchEvent<?> event, Path currentPath) {
                Log.log("文件被修改: " + event.context());
                scan();
            }
            @Override
            public void onDelete(WatchEvent<?> event, Path currentPath) {
                Log.log("文件被删除: " + event.context());
                scan();
            }
            @Override
            public void onOverflow(WatchEvent<?> event, Path currentPath) {
                Log.log("文件被覆盖: " + event.context());
                scan();
            }
        }).start();
    }
    
    //扫描文件
    private static void scan()
    {
        Log.log("开始扫描文件!");
        //没有文件，不需要重新生成索引文件
        if(FileUtil.isDirEmpty(FileUtil.file(Parameter.local_file))) {Log.log("空目录,结束扫描文件!");return;}
        //文件名称, 文件大小, 最后修改时间
        //目录下的所有文件
        File[] files = FileUtil.ls(Parameter.local_file);
        //生成索引的空白json对象
        JSONObject datas = JSONUtil.createObj();
        //对比每一个文件的修改时间，如果修改时间发生了变化，则更新索引文件
        for (int i = 0; i < files.length; i++) 
        {
        	//文件对象，不是一个文件则不进行操作
            File file = files[i];
            if(!file.isFile()) {continue;}
            //生成文件索引
            JSONObject data = JSONUtil.createObj();
            data.set("name", file.getName())//文件名称
            .set("size", FileUtil.size(file))//文件大小
            .set("md5", SecureUtil.md5(file));//文件md5
            datas.set(data.getStr("name"), data);
            //将文件复制到临时目录，如果临时目录中不存在该文件或者文件md5不同，则复制文件
            File tmp_file = FileUtil.file(Parameter.tmp_path + file.getName());
            if(!FileUtil.exist(tmp_file) || !Objects.equals(SecureUtil.md5(file), SecureUtil.md5(tmp_file)))
            {
            	FileUtil.copy(file, FileUtil.file(Parameter.tmp_path + file.getName()), true);
            }
            Log.log("data: "+data.toString());
        }
        Log.log("datas: "+datas.toString());
        //重新生成索引文件
        FileWriter writer = new FileWriter(Parameter.indexes_path);
        writer.write(datas.toString());
        //处理被删除的文件，如果文件名称在索引中不存在[在原目录中被删除了]，则删除临时目录中的文件
        files = FileUtil.ls(Parameter.tmp_path);
        for (int i = 0; i < files.length; i++) 
        {
        	//文件对象，不是一个文件则不进行操作
            File file = files[i];
            if(!file.isFile() || Objects.equals(Parameter.indexes, file.getName())) {continue;}
            JSONObject data = datas.getJSONObject(file.getName());
            if(data == null || data.isEmpty())
            {
                file.delete();
            }
        }
        Log.log("结束扫描文件!");
    }
}